package com.xyzq.simpson.apm.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.xyzq.simpson.apm.web.entity.GlobalBrief;
import com.xyzq.simpson.apm.web.entity.GlobalHeatMap;
import com.xyzq.simpson.apm.web.entity.SlowItem;
import com.xyzq.simpson.apm.web.service.influx.HttpExecuteService;
import com.xyzq.simpson.apm.web.utils.DurationUtil;
import com.xyzq.simpson.apm.web.utils.ResponseEntity;
import com.xyzq.simpson.apm.web.utils.TimeUtils;
import com.xyzq.simpson.hibbert.storage.es.dao.IMetadataQueryDAO;
import com.xyzq.simpson.hibbert.storage.es.dao.IMetricsQueryDAO;
import com.xyzq.simpson.hibbert.storage.es.manager.EsQueryManager;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

/**
 * @Description:
 * @date 2021/5/22 20:44
 */
@Controller
@RequestMapping("apm/metrics")
public class MetricsController {

    @RequestMapping(value = "", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity metrics(@RequestBody Map<String, Object> json) throws Exception {
        JSONObject res = new JSONObject();
        String serviceId = (String) json.get("serviceId");
        String instanceId = (String) json.get("instanceId");
        long startTimeStamp = DurationUtil.getStartTimeStamp(json);
        long endTimeStamp = DurationUtil.getEndTimeStamp(json);
        List<Map<String, Object>> nav = (List<Map<String, Object>>) json.get("nav");
        List<String> itemList = new ArrayList<>();
        nav.forEach(x -> itemList.add(""+x.get("d")));
        for(String item : itemList) {
            res.put(item, dealMetrics(item, serviceId, instanceId, startTimeStamp, endTimeStamp));
        }
        return new ResponseEntity().success(res);
    }

    private Object dealMetrics(String item, String serviceId, String instanceId,
                               long startTimeStamp, long endTimeStamp) throws Exception {
        IMetadataQueryDAO metadataQueryDAO = EsQueryManager.instance().getService(IMetadataQueryDAO.class);
        IMetricsQueryDAO metricsQueryDAO = EsQueryManager.instance().getService(IMetricsQueryDAO.class);
        if (item.equalsIgnoreCase("GlobalBrief")) {
            GlobalBrief globalBrief = new GlobalBrief();
            List<String> allServices = metadataQueryDAO.getAllServices(startTimeStamp, 0L);
            globalBrief.setNumOfService(allServices.size());
            globalBrief.setNumOfEndpoint(365);
            return globalBrief;
        } else if (item.equalsIgnoreCase("GlobalCPMHttp")) {
            List<Map<String, Object>> globalCPM = HttpExecuteService.getGlobalCPMHttp(startTimeStamp, endTimeStamp);
            List<SlowItem> list = new ArrayList<>(10);
            for (int i = 0; i < 10 && i < globalCPM.size(); i++) {
                list.add(new SlowItem<Long>(i + 1, "" + globalCPM.get(i).get("project"),
                        Double.valueOf("" + globalCPM.get(i).get("meanCount")).longValue()));
            }
            return list;
        }  else if (item.equalsIgnoreCase("GlobalCPMRpc")) {
            List<Map<String, Object>> globalCPM = HttpExecuteService.getGlobalCPMRpc(startTimeStamp, endTimeStamp);
            List<SlowItem> list = new ArrayList<>(10);
            for (int i = 0; i < 10 && i < globalCPM.size(); i++) {
                list.add(new SlowItem<Long>(i + 1, "" + globalCPM.get(i).get("project"),
                        Double.valueOf("" + globalCPM.get(i).get("meanCount")).longValue()));
            }
            return list;
        } else if (item.equalsIgnoreCase("GlobalSlowHttpServices")) {
            List<SlowItem> list = new ArrayList<>(10);
            List<Map<String, Object>> res = metricsQueryDAO.queryGlobalSlowServices(startTimeStamp, endTimeStamp, "HTTP");
            for (int i = 0; i < 10 && i < res.size(); i++) {
                list.add(new SlowItem<>(i + 1, "" + res.get(i).get("project"),
                        "" + res.get(i).get("meanCost") + "ms"));
            }
            return list;
        } else if (item.equalsIgnoreCase("GlobalSlowRpcServices")) {
            List<SlowItem> list = new ArrayList<>(10);
            List<Map<String, Object>> res = metricsQueryDAO.queryGlobalSlowServices(startTimeStamp, endTimeStamp, "RPC");
            for (int i = 0; i < 10 && i < res.size(); i++) {
                list.add(new SlowItem<>(i + 1, "" + res.get(i).get("project"),
                        "" + res.get(i).get("meanCost") + "ms"));
            }
            return list;
        } else if (item.equalsIgnoreCase("GlobalApdex")) {
            List<SlowItem> list = new ArrayList<>(10);
            List<Map<String, Object>> res = metricsQueryDAO.queryGlobalApdex(startTimeStamp, endTimeStamp);
            for (int i = 0; i < 10 && i < res.size(); i++) {
                list.add(new SlowItem<String>(i + 1, "" + res.get(i).get("project"),
                        "" + res.get(i).get("apdex") + "%"));
            }
            return list;
        } else if (item.equalsIgnoreCase("GlobalHeatMap")) {
            //固定为一周的跨度
            String[] date = TimeUtils.past7Days();
            List<Long> allHours = TimeUtils.past7DaysAllHours(date[0]);
            startTimeStamp = TimeUtils.getStartTimestampByDate(date[0]);
            endTimeStamp = TimeUtils.getEndTimestampByDate(date[6]);
            Map<Long, Integer> map = metricsQueryDAO.queryGlobalTimeIntervalCount(startTimeStamp, endTimeStamp);
            List<Integer> values =  new ArrayList<>(7*24);
            for(Long k : allHours) {
                if(null != map.get(k)) {
                    values.add(map.get(k));
                } else {
                    values.add(0);
                }
            }
            List<int[]> list = new ArrayList<>(7);
            for(int i = 0; i < 7; i++) {
                for(int j = 0; j < 24; j++) {
                    int[] arr = new int[3];
                    arr[0] = i;
                    arr[1] = j;
                    arr[2] = values.get(24*i+j);
                    list.add(arr);
                }
            }
            return new GlobalHeatMap(list, date);
        } else if (item.equalsIgnoreCase("GlobalExceptionCount")) {
            List<SlowItem> list = new ArrayList<>(10);
            List<Map<String, Object>> res = metricsQueryDAO.queryGlobalExceptionCount(startTimeStamp, endTimeStamp);
            for (int i = 0; i < 10 && i < res.size(); i++) {
                list.add(new SlowItem<String>(i + 1, "" + res.get(i).get("project"),
                        "" + res.get(i).get("count")));
            }
            return list;
        }
        return null;
    }
}
